package lock;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * CAS
 乐观锁是一种乐观思想，假定当前环境是读多写少，遇到并发写的概率比较低，读数据时认为别的线程不会正在进行修改（所以没有上锁）。
 写数据时，判断当前 与期望值是否相同，如果相同则进行更新（更新期间加锁，保证是原子性的）。

 Java中的乐观锁： CAS，比较并替换，比较当前值（主内存中的值），与预期值（当前线程中的值，主内存中值的一份拷贝）是否一样，一样则更新，否则继续进行CAS操作。
 *              CAS原子操作类：AtomicInteger、AtomicLong、AtomicBoolean、AtomicReference等。

 乐观锁的优点
        无锁竞争：乐观锁的主要优势是减少了锁的竞争，因为在更新数据时并没有加锁。
        提高并发性能：适用于读操作多于写操作的场景，可以提高系统的并发性能。
 乐观锁的缺点
        ABA 问题：乐观锁基于版本号或者 CAS，当值发生变更后被修改为相同的值时，可能无法发现数据冲突（即值的变化不会影响判断），这种情况称为 "ABA 问题"。
        重试开销：如果并发冲突较多，线程需要频繁重试，可能导致性能下降。
 *
 */
public class OptimisticLockExample {
    private static AtomicInteger counter = new AtomicInteger(0);

    public static void main(String[] args) {
        //1.创建三个线程
       Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                // CAS 操作：如果 counter 的值与 expectedValue 相等，则将 counter 的值设置为 newValue
                while (true) {
                    int currentValue = counter.get();
                    int newValue = currentValue + 1;
                    if (counter.compareAndSet(currentValue, newValue)) {
                        break;  // 如果更新成功，跳出循环
                    }
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                // CAS 操作：如果 counter 的值与 expectedValue 相等，则将 counter 的值设置为 newValue
                while (true) {
                    int currentValue = counter.get();
                    int newValue = currentValue + 1;
                    if (counter.compareAndSet(currentValue, newValue)) {
                        break;  // 如果更新成功，跳出循环
                    }
                }
            }
        });

        Thread thread3  = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                // CAS 操作：如果 counter 的值与 expectedValue 相等，则将 counter 的值设置为 newValue
                while (true) {
                    int currentValue = counter.get();
                    int newValue = currentValue + 1;
                    if (counter.compareAndSet(currentValue, newValue)) {
                        break;  // 如果更新成功，跳出循环
                    }
                }
            }
        });

        thread1.start();
        thread2.start();
        thread3.start();

        try {
            thread1.join();
            thread2.join();
            thread3.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 输出最终的计数值
        System.out.println("Final Counter Value: " + counter.get());
    }
}
